package com.alks.common.utils.stringUtils;

import com.alks.entity.data.entity.StyleProductionProcess;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.*;

public class ZStringUtils extends StringUtils {
    private static final String NULLSTR = "";

    private static final char SEPARATOR = '_';

    private static final String[] ILLEGAL_CHARS = new String[]{"<", ">", "\"", "\\/", "\\?", " ", "\\\\", "\\*"};

    public static <T> T nvl(T value, T defaultValue) {
        return (value != null) ? value : defaultValue;
    }

    public static boolean isEmpty(Collection<?> coll) {
        return (isNull(coll) || coll.isEmpty());
    }

    public static boolean isNotEmpty(Collection<?> coll) {
        return !isEmpty(coll);
    }

    public static boolean isEmpty(Object[] objects) {
        return (isNull(objects) || objects.length == 0);
    }

    public static boolean isNotEmpty(Object[] objects) {
        return !isEmpty(objects);
    }

    public static boolean isEmpty(Map<?, ?> map) {
        return (isNull(map) || map.isEmpty());
    }

    public static boolean isNotEmpty(Map<?, ?> map) {
        return !isEmpty(map);
    }

    public static boolean isEmpty(String str) {
        return (isNull(str) || "".equals(str.trim()));
    }

    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    public static boolean isNull(Object object) {
        return (object == null);
    }

    public static boolean isNotNull(Object object) {
        return !isNull(object);
    }

    public static boolean isArray(Object object) {
        return (isNotNull(object) && object.getClass().isArray());
    }

    public static String trim(String str) {
        return (str == null) ? "" : str.trim();
    }

    public static String substring(String str, int start) {
        if (str == null)
            return "";
        if (start < 0)
            start = str.length() + start;
        if (start < 0)
            start = 0;
        if (start > str.length())
            return "";
        return str.substring(start);
    }

    public static String substring(String str, int start, int end) {
        if (str == null)
            return "";
        if (end < 0)
            end = str.length() + end;
        if (start < 0)
            start = str.length() + start;
        if (end > str.length())
            end = str.length();
        if (start > end)
            return "";
        if (start < 0)
            start = 0;
        if (end < 0)
            end = 0;
        return str.substring(start, end);
    }

    public static String format(String template, Object... params) {
        if (isEmpty(params) || isEmpty(template))
            return template;
        return StrFormatter.format(template, params);
    }

    public static String toUnderScoreCase(String str) {
        if (str == null)
            return null;
        StringBuilder sb = new StringBuilder();
        boolean preCharIsUpperCase = true;
        boolean curreCharIsUpperCase = true;
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (i > 0) {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            } else {
                preCharIsUpperCase = false;
            }
            curreCharIsUpperCase = Character.isUpperCase(c);
            if (i < str.length() - 1)
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
                sb.append('_');
            } else if (i != 0 && !preCharIsUpperCase && curreCharIsUpperCase) {
                sb.append('_');
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    public static boolean inStringIgnoreCase(String str, String... strs) {
        if (str != null && strs != null)
            for (String s : strs) {
                if (str.equalsIgnoreCase(trim(s)))
                    return true;
            }
        return false;
    }

    public static String convertToCamelCase(String name) {
        StringBuilder result = new StringBuilder();
        if (name == null || name.isEmpty())
            return "";
        if (!name.contains("_"))
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        String[] camels = name.split("_");
        for (String camel : camels) {
            if (!camel.isEmpty()) {
                result.append(camel.substring(0, 1).toUpperCase());
                result.append(camel.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    public static String toCamelCase(String s) {
        if (s == null)
            return null;
        if (s.indexOf('_') == -1)
            return s;
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '_') {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public static String replaceIllegalChar(String str) {
        if (Objects.isNull(str))
            return null;
        for (int i = 0; i < ILLEGAL_CHARS.length; i++)
            str = str.replaceAll(ILLEGAL_CHARS[i], "-");
        return str;
    }

    public static <T> T cast(Object obj) {
        return (T) obj;
    }

    public static <T> T defaultValue(T obj, T defaultVal) {
        if (isNull(obj))
            return defaultVal;
        return obj;
    }

    private static final String[] STR_NUMBER = new String[]{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};

    private static final String[] STR_UNIT = new String[]{
            "", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾",
            "佰", "仟"};

    private static final String[] STR_UNIT2 = new String[]{"角", "分", "厘"};

    public static String getInteger(String num) {
        if (num.indexOf(".") != -1)
            num = num.substring(0, num.indexOf("."));
        num = (new StringBuffer(num)).reverse().toString();
        StringBuffer temp = new StringBuffer();
        for (int i = 0; i < num.length(); i++) {
            temp.append(STR_UNIT[i]);
            temp.append(STR_NUMBER[num.charAt(i) - 48]);
        }
        num = temp.reverse().toString();
        num = numReplace(num, "零拾", "零");
        num = numReplace(num, "零佰", "零");
        num = numReplace(num, "零千", "零");
        num = numReplace(num, "零万", "零");
        num = numReplace(num, "零亿", "零");
        num = numReplace(num, "零零", "零");
        num = numReplace(num, "亿万", "零");
        if (num.lastIndexOf("零") == num.length() - 1)
            num = num.substring(0, num.length() - 1);
        return num;
    }

    public static String getDecimal(String num) {
        if (num.indexOf(".") == -1)
            return "";
        num = num.substring(num.indexOf(".") + 1);
        num = (new StringBuffer(num)).reverse().toString();
        StringBuffer temp = new StringBuffer();
        for (int i = 0; i < num.length(); i++) {
            temp.append(STR_UNIT2[i]);
            temp.append(STR_NUMBER[num.charAt(i) - 48]);
        }
        num = temp.reverse().toString();
        num = numReplace(num, "零角", "零");
        num = numReplace(num, "零分", "零");
        num = numReplace(num, "零厘", "零");
        num = numReplace(num, "零零", "零");
        if (num.lastIndexOf("零") == num.length() - 1)
            num = num.substring(0, num.length() - 1);
        return num;
    }

    public static String numReplace(String num, String oldStr, String newStr) {
        while (num.indexOf(oldStr) != -1)
            num = num.replaceAll(oldStr, newStr);
        return num;
    }

    public static String convert(double d) {
        DecimalFormat df = new DecimalFormat("#0.###");
        String strNum = df.format(d);
        if (strNum.indexOf(".") != -1) {
            String num = strNum.substring(0, strNum.indexOf("."));
            if (num.length() > 12) {
                System.out.println("数字太大，不能完成转换");
                return "";
            }
        }
        String point = "";
        if (strNum.indexOf(".") != -1) {
            point = "元";
        } else {
            point = "元整";
        }
        String result = getInteger(strNum) + point + getDecimal(strNum);
        if (result.startsWith("元"))
            result = result.substring(1, result.length());
        return result;
    }

    //判断特定字符串是否为空
    public static boolean noeNotNull(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String name = "";
        for (int i = 0; i < fields.length; i++) {
            //属性名
            name = fields[i].getName();
            if ("pageSize".equals(name)) {
                continue;
            }
            if ("pageNum".equals(name)) {
                continue;
            }
            if ("custPrice".equals(name)) {
                continue;
            }
            if ("downFlag".equals(name)) {
                continue;
            }
            //当前属性名的值
            Object fieldValueByName = getFieldValueByName(name, o);

            //如果是String，判断空字符串""
            if (fields[i].getType().equals(String.class)) {
                String s = (String) fieldValueByName;
                if (!StringUtils.isEmpty(s)) {
                    return true;
                }
            } else {
                //值为null
                if (fieldValueByName != null)
                    return true;
            }

        }
        return false;
    }

    public static List<String> getProcess(Object o) {
        List<String> processList = new ArrayList<>();
        Field[] fields = o.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            String name = fields[i].getName();
            if (name.contains("process")) {
                Object fieldValueByName = getFieldValueByName(name, o);
                String s = (String) fieldValueByName;
                if (s == null) {
                    s = "";
                }
                if (s.contains("二次改刀") || s.contains("chặt lần 2")) {
                    processList.add(s);
                }
                if (s.contains("贴流水标") || s.contains("dán tem số thứ tự")) {
                    processList.add(s);
                }
            }
        }
        return processList;
    }

    public static boolean noeNotNullProcess(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String name = "";
        for (int i = 0; i < fields.length; i++) {
            //属性名
            name = fields[i].getName();
            if (!name.contains("process")) {
                continue;
            }
            //当前属性名的值
            Object fieldValueByName = getFieldValueByName(name, o);

            //如果是String，判断空字符串""
            if (fields[i].getType().equals(String.class)) {
                String s = (String) fieldValueByName;
                if (!StringUtils.isEmpty(s)) {
                    return true;
                }
            } else {
                //值为null
                if (fieldValueByName != null)
                    return true;
            }

        }
        return false;
    }

    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            return null;
        }
    }

    public static boolean isProcessCf(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String name = "";
        List<String> list = new ArrayList<>();
        Set<String> nList = new HashSet<>();
        for (int i = 0; i < fields.length; i++) {
            //属性名
            name = fields[i].getName();
            if (!name.contains("process")) {
                continue;
            }
            //当前属性名的值
            Object fieldValueByName = getFieldValueByName(name, o);
            //如果是String，判断空字符串""
            if (fields[i].getType().equals(String.class)) {
                String s = (String) fieldValueByName;
                if (ZStringUtils.isNotEmpty(s)) {
                    list.add(s);
                    nList.add(s);
                }
            }
        }
        if (list.size() > nList.size()) return true;
        return false;
    }
}
